//
//  DPUtilities.m
//  UITestingKit
//
//  Created by Ofri Wolfus on 30/01/07.
//  Copyright 2007 Ofri Wolfus. All rights reserved.
//

#import "DPUtilities.h"


static void _DPMaintainAutoreleasePool(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
	NSAutoreleasePool **pool = info;
	[*pool release];
	*((NSAutoreleasePool **)info) = [[NSAutoreleasePool alloc] init];
}

static void _DPReleasePool(const void *info) {
	NSAutoreleasePool **pool = (void *)info;
	[*pool release];
	free((void *)info);
}

void DPSetUpAutoreleasePool(NSString *runLoopMode) {
	CFRunLoopRef rl = CFRunLoopGetCurrent();
	CFStringRef mode = CFRetain((CFStringRef)runLoopMode) ?: CFRunLoopCopyCurrentMode(rl);
	
	if (mode) {
		NSAutoreleasePool **p = malloc(sizeof(NSAutoreleasePool **));
		CFRunLoopObserverContext context = {
			0,				// version
			p,				// info
			NULL,			// retain
			_DPReleasePool,	// release
			NULL			// copy description
		};
		*p = [[NSAutoreleasePool alloc] init];
		CFRunLoopObserverRef observer = CFRunLoopObserverCreate(kCFAllocatorDefault,
																kCFRunLoopEntry, true, 0,
																_DPMaintainAutoreleasePool,
																&context);
		
		CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, mode);
		CFRelease(mode);
	}
}

BOOL DPGetPIDOfProcess(NSString *bundleIdentifier, pid_t *pid) {
	ProcessSerialNumber psn = { kNoProcess, kNoProcess };
	
	while (GetNextProcess(&psn) == noErr) {
		NSDictionary *info = (NSDictionary *)ProcessInformationCopyDictionary(&psn, kProcessDictionaryIncludeAllInformationMask);
		
		if ([[info objectForKey:(NSString *)kCFBundleIdentifierKey] isEqualToString:bundleIdentifier]) {
			if (pid)
				*pid = [[info objectForKey:@"pid"] intValue];
			
			return YES;
		}
	}
	
	return NO;
}
